﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using NLog;
using SellAvi.Classes;
using SellAvi.Model;
using SellAvi.Services;
using SellAvi.Views;

namespace SellAvi.ViewModel
{
    public partial class MailingViewModel : AdsParserViewModel
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        public RelayCommand OpenPrepareMailingCommand { get; set; }
        public RelayCommand GetRecepientsCommand { get; set; }
        public RelayCommand CleanSendToCollectionCommand { get; set; }
        public RelayCommand MarkMailCommand { get; set; }
        public RelayCommand MessageSynthesisCommand { get; set; }
        public RelayCommand<AvitoMailingItem> RowClickCommand { get; set; }

        //Автоответчик
        public RelayCommand SocketOpenCommand { get; set; }
        public RelayCommand OpenChatRoomsCommand { get; set; }
        public RelayCommand ReloadChatInfoCommand { get; set; }


        public MailingViewModel(IDataAccessService serviceProxy)
            : base(serviceProxy)
        {
            OpenPrepareMailingCommand = new RelayCommand(OpenPrepareMailingWindow);
            CleanSendToCollectionCommand = new RelayCommand(CleanSendToCollection);
            MarkMailCommand = new RelayCommand(CreateMailTask);
            GetRecepientsCommand = new RelayCommand(GetRecepients);
            MessageSynthesisCommand = new RelayCommand(() => RegenerateMessageText(mode: 1));
            RowClickCommand = new RelayCommand<AvitoMailingItem>(LinkClick);
            
            //Автоответчик
            SocketOpenCommand = new RelayCommand(SocketOpen);
            OpenChatRoomsCommand = new RelayCommand(OpenSocketWindow);
            ReloadChatInfoCommand = new RelayCommand(ReloadChatInfo);
            MessageText = "Для покупки товара обратитесь по телефону 8(812)905-33-51 или на сайт SeoRed ru";

            MailingSpeed = 60;
            MailingCollection = new ObservableCollection<AvitoMailingItem>();
            MessageTemplate = "[Добрый день|Здравствуйте|Приветствую][!|,| ] [Вы продаете|Продаете|Где можно посмотреть|Могу купить] [AvitoProductName][?| |??]";

        }

        private void OpenPrepareMailingWindow()
        {
            new WindowPrepareMailing().Show();
        }
        private void OpenSocketWindow()
        {
            new WindowAutoReply().Show();
        }

        private void CleanSendToCollection()
        {
            MailingCollection.Clear();
            RaisePropertyChanged("RecepientCount");
        }

        private void GetRecepients()
        {
            if (Webclient != null)
            {
                if (!base.ParseInProgress)
                {
                    ParseInProgress = true;
                    //_cancellationToken = new CancellationTokenSource();
                    Task.Factory.StartNew(_ => ParseIndex(), new CancellationTokenSource())
                        .ContinueWith(_ => { ParseInProgress = false; RaisePropertyChanged("RecepientCount"); });
                }

            }
            else
            {
                MessageBox.Show("Для выполнения операции необходима авторизация в программе!", "Требуется авторизация",
                    MessageBoxButton.OK, MessageBoxImage.Asterisk);
            }
        }
        private void ParseIndex()
        {
            var app = new AvitoParserProcessor(Webclient, SPS);
            SearchIndexCollection = app.DownloadIndexUrlsAsync(SPS.DefaultParseUrl).Result;
            Application.Current.Dispatcher.Invoke(new Action(() => RegenerateMessageText(mode: 0)));
        }

        private static void LinkClick(AvitoMailingItem selectedMailItem)
        {
            var item = selectedMailItem as AvitoMailingItem;
            if (item != null)
            {
                IEHelpers.OpenWebBrowser("https://www.avito.ru/" + item.AdId);
            }
        }
        private void CreateMailTask()
        {
            var taskList = new List<AvitoTask>();
            foreach (var mailItem in MailingCollection)
            {
                var tms = new TaskMailSender((AvitoMailingItem)mailItem) { TaskDelay = MailingSpeed };
                taskList.Add(tms);
            }
            Messenger.Default.Send<List<AvitoTask>>(taskList);
        }

        public ObservableCollection<AvitoMailingItem> MailingCollection { get; set; }
        public List<AvitoSearchItem> SearchIndexCollection { get; set; }

        public string MessageTemplate { get; set; }
        public int MailingSpeed { get; set; }



#region Генерирование текста рассылки
        private static readonly Random rnd = new Random();
        private void RegenerateMessageText(int mode = 0)
        {
            if (mode == 1)
                MailingCollection.Clear();
            if (SearchIndexCollection != null && SearchIndexCollection.Count > 0)
            {
                foreach (AvitoSearchItem toItem in SearchIndexCollection)
                {
                    MailingCollection.Add(new AvitoMailingItem()
                    {
                        SendToUrl = toItem.AdUrl.ToString(),
                        MessageText = MessageSynthesis(toItem),

                    });
                }
            }
            else
            {
                MessageBox.Show("Отсутствует список получателей!");
            }
        }

        private string MessageSynthesis(AvitoSearchItem asi)
        {

            var messageText = MessageTemplate;
            var bracketsGroupsRegexp = new Regex(@"\[(?<brackets>.+?)\]", RegexOptions.IgnoreCase);
            var bracketMatches = bracketsGroupsRegexp.Matches(MessageTemplate);
            foreach (Match match in bracketMatches)
            {
                var el = match.Groups["brackets"].Value;
                if (el.Contains("|"))
                {
                    var sub = el.Split('|');
                    var n = sub.Length;
                    var i = rnd.Next(1, n + 1) - 1;
                    messageText = messageText.Replace(match.Groups[0].Value, sub[i]);
                }
                else if (asi != null)
                {
                    switch (el)
                    {
                        case "AvitoProductName":
                            messageText = messageText.Replace("[AvitoProductName]", ApplyWordMorphology(asi.AdTitle));
                            break;
                    }

                }

            }
            return messageText;
        }

        private string ApplyWordMorphology(string text)
        {
            text = text.Replace(".", "").Replace(",", "").Replace("продам", "").Replace("-", "").Replace("\"", "").Trim();
            var wordLimit = 2;
            var conjugatedText = "";
            var replacementDictionary = new Dictionary<string, string>
            {
                {"а","у"},
                {"ая","ую"}
            };
            Regex rgx = new Regex(@"$(?<=(а|ая))");
            var words = text.Split(' ').Take(wordLimit).Where(x => x.Length > 3).ToList(); //предлоги 'на' 'для'

            foreach (var word in words)
            {
                if (rgx.Match(word).Success)
                {
                    var wordEnding = rgx.Match(word).Groups[1].Value;
                    conjugatedText += (" " + word.Replace(wordEnding, replacementDictionary[wordEnding]));
                }
                else
                {
                    conjugatedText += (" " + word);
                }
            }
            return conjugatedText.Trim().ToLowerInvariant();
        }
#endregion
    }
}
